package cn.itcast.nems.journal.service.impl;

import cn.itcast.nems.base.dao.entity.E2Clazz;
import cn.itcast.nems.base.dao.mapper.E2ClazzMapper;
import cn.itcast.nems.journal.service.JournalTransferCommonService;
import cn.itcast.nems.studentrecord.dao.entity.JournalTransferType;
import cn.itcast.nems.studentrecord.dao.entity.StudentRecord;
import cn.itcast.nems.studentrecord.service.settlement.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

@Service
@RequiredArgsConstructor
public class JournalTransferCommonServiceImpl implements JournalTransferCommonService {

    private final E2ClazzMapper e2ClazzMapper;

    @Override
    public DefaultSettlementCalculator getCalculatorInstance(JournalTransferType journalTransferType) {
        return switch (journalTransferType) {
            case EXCHANGE -> new SettlementCalculatorExchange();
            case DELAY -> new SettlementCalculatorDelay();
            case TRANSFER -> new SettlementCalculatorTransfer();
            case SUSPENSION -> new SettlementCalculatorSuspension();
        };
    }

    @Override
    public SettlementResult calculate(JournalTransferType journalTransferType, SettlementData data) {
        return getCalculatorInstance(journalTransferType).calculate(data);
    }

    @Override
    public SettlementResult calculate(JournalTransferType journalTransferType, StudentRecord studentRecord, LocalDateTime outDate) {
        var e2clazz = e2ClazzMapper.selectOne(new QueryWrapper<E2Clazz>()
                .lambda().eq(E2Clazz::getClazzId, studentRecord.getClazzId()));
        return calculate(journalTransferType, studentRecord, outDate, e2clazz);
    }

    @Override
    public SettlementResult calculate(JournalTransferType journalTransferType, StudentRecord studentRecord, LocalDateTime outDate, E2Clazz sourceClazz) {
        return calculate(journalTransferType, new SettlementData(
                studentRecord.getPrice(),
                studentRecord.getAmountDue(),
                studentRecord.getActualAmountDue(),
                studentRecord.getPaidAmount(),
                studentRecord.getTransferFromAmount(),
                studentRecord.getRefundAmount(),
                sourceClazz.getClazzId(),
                sourceClazz.getStartDate(),
                sourceClazz.getPredictionGraduationDate(),
                studentRecord.getInDate(),
                outDate,
                sourceClazz.getDelayFlag(),
                sourceClazz.getSuspensionFlag()
        ));
    }
}
